﻿using System;

namespace PoolKit
{
    /// <summary>
    /// Functional shortcut for creating a <see cref="ResourceCreationStrategy{TResource}"/>
    /// </summary>
    /// <typeparam name="TResource">Type of resource the strategy can handle</typeparam>
    public class ResourceCreationFunction<TResource> : ResourceCreationStrategy<TResource>
    {
        private readonly Func<TResource> _creationFunction;
        private readonly ThreadingContract _threadingContract;

        /// <summary>
        /// Creates a resource creation strategy from the provided function
        /// </summary>
        /// <param name="creationFunction">Function that defines the strategy</param>
        /// <param name="threadingContract">Specifies the threading contract exposed by the strategy (whether it is safe to call into the strategy simultaneously from several threads).</param>
        /// <exception cref="ArgumentNullException"></exception>
        public ResourceCreationFunction(Func<TResource> creationFunction, ThreadingContract threadingContract)
        {
            if (creationFunction == null) throw new ArgumentNullException("creationFunction");

            _creationFunction = creationFunction;
            _threadingContract = threadingContract;
        }

        /// <summary>
        /// True, if it is safe to call into the strategy simultaneously from several threads; False - otherwise.
        /// </summary>
        public override ThreadingContract ThreadingContract
        {
            get
            {
                return _threadingContract;
            }
        }

        /// <summary>
        /// Creates a new resource (<typeparamref name="TResource"/>)
        /// </summary>
        /// <returns>Newly created resource (<typeparamref name="TResource"/>)</returns>
        public override TResource Create()
        {
            return _creationFunction.Invoke();
        }
    }
}